#!/usr/bin/ruby
# encoding: utf-8

require 'arbi'
require 'mbox'

class Float
    def s
        ('%.1f' % self).gsub(/\.0$/, '')
    end
end

class Cache
    def initialize(time, default = nil, &block)
        @delay = time.to_i
        @block = block
        @default = default
        unless block
            raise "Insert a block"
        end
        @thread = Thread.new{
            while true
                res = @block.call
                @mutex.lock
                @res = res
                @mutex.unlock
                sleep @delay
            end
        }
        @mutex = Mutex.new
    end

    def get
        @mutex.lock
        res = @res
        @mutex.unlock
        res || @default
    end

    alias :to_s :get

    def inspect
        get.inspect
    end

    def finalize
        @thread.kill
    end

    alias :close :finalize
end

pacman = Cache.new(60, "0"){
    `pacman -Qu`.split(/\r?\n/).length
}

mailt = Thread.new{
    while true
        mailio = IO.popen("/usr/bin/fetchmail -m 'procmail -d %T'", 'w+')
        mailio.print "\n"
        mailio.flush
        while mailio.gets; end
        mailio.close
        sleep 1790
    end
}

mail = Cache.new(120, "0"){
    Mbox.open('Inbox', 'Mail').select{|x|x.unread?}.size
}

uni = Cache.new(2){
    `risultati -c`.chomp
}

pacmanc = Cache.new(10){
    `pc-notify`.chomp
}

def icon(file)
    "^i(#{File.join(ENV['HOME'], '.dzen2', file)})"
end

Arbi.connect

dzen = IO.popen("/usr/bin/dzen2 #{ARGV.map(&:inspect).join(' ')}", 'w')
@t = true

[:KILL, :INT, :TERM].each{|x|
    trap(x){
        dzen.close
        mailt.kill
    }
}

while true
    system("mocp -S 2>/dev/null") unless File.exists? File.join(ENV['HOME'], '.moc', 'pid')

    unless @t
        sleep 2
    else
        @t = !@t
    end

    dzen.print "#{uni.to_s} #{pacmanc.to_s} "
    
    #=begin MUSIC
    dzen.print "#{icon 'music.xbm'}"

    case `mocp -i 2>/dev/null`.scan(/^State: (.+?)$/)[0][0]
        when "PLAY"
            dzen.print " ^ca(1,mocp -G)#{icon 'play.xbm'}^ca()"
        when "PAUSE"
            dzen.print " ^ca(1,mocp -G)#{icon 'pause.xbm'}^ca()"
        when "STOP"
            dzen.print " ^ca(1,mocp -p)#{icon 'stop.xbm'}^ca()"
    end
    #=end

    #=begin BATTERY
    dzen.print " #{icon 'bat.xbm'} "
    batteries = Arbi.get "battery"
    if batteries["BAT0"] == {'sanity' => false, 'state' => false, 'percent' => false}
        dzen.print "AC"
    else
        dzen.print batteries["AVERAGE"]["percent"]
    end
    #=end

    #=begin CPU
    dzen.print " #{icon 'cpu.xbm'} #{Arbi.get("cpu")["cpu0"]}"
    #=end

    #=begin RAM
    dzen.print " #{icon 'ram.xbm'} #{Arbi.get("ram")["used"]}"
    #=end

    #=begin THERMAL
    dzen.print " #{icon 'tem.xbm'} #{Arbi.get("thermal")["AVERAGE"]["temperature"]}\xB0C"
    #=end

    #=begin MAILS
    dzen.print " #{icon 'mail.xbm'} #{mail.to_s}"
    #=end

    #=begin DISKS SPACE
    disks = Arbi.get "diskstats"
    dzen.print " #{icon 'hdd.xbm'}"
    disks.each{|disk|
        if ['/dev/sda6', '/dev/sda7', '/dev/sda3'].include? disk['device']
            dzen.print " #{disk['point']} #{disk['usage']}"
        end
    }
    #=end

    #=begin PACMAN
    dzen.print " #{icon 'arch.xbm'} #{pacman.to_s}"
    #=end

    #=begin NET
    net = Arbi.get("net")
    if net['wlan0'][:state]
        dzen.print " #{icon 'wifi.xbm'} #{net["wlan0"][:essid]}:#{net["wlan0"][:quality]}"
        dzen.print " #{icon 'up.xbm'} #{net['wlan0'][:up].s} #{icon 'down.xbm'} #{net['wlan0'][:down].s}"
    elsif net['eth0'][:state]
        dzen.print " #{icon 'up.xbm'} #{net['eth0'][:up].s} #{icon 'down.xbm'} #{net['eth0'][:down].s}"
    end
    #=end

    #=begin DATE
    dzen.print " | #{Time.now.strftime("%d/%m/%Y %H:%M")}\n"
    #=end

    dzen.flush
end
